package models

import (
	"github.com/astaxie/beego/orm"
	"strconv"
	"fmt"
	"encoding/base64"
)

type SysMenu struct {
	Id      int    `orm:"column(id);auto"`
	AppId   int    `orm:"column(app_id)" description:"应用ID"`
	Name    string `orm:"column(name);size(10)" description:"菜单名称"`
	Path    string `orm:"column(path);size(40)" description:"相对路径"`
	MainId  int    `orm:"column(main_id)" description:"主菜单ID"`
	SortId  int    `orm:"column(sort_id)" description:"排序ID"`
	IsOuter int8   `orm:"column(is_outer)" description:"是否外部链接"`
}

type FormatSysMenu struct {
	Sort    int
	AppName string
	SysMenu
}

type SecondMenu struct {
	Sort       int
	AppName    string
	ParentName string
	SysMenu
}

func (t *SysMenu) TableName() string {
	return "sys_menu"
}

func init() {
	orm.RegisterModel(new(SysMenu))
}

func GetMenuList(appId, page, pageSize int) ([]*FormatSysMenu, int64) {
	offset := (page - 1) * pageSize
	formatSysMenus := make([]*FormatSysMenu, 0)
	count := 0
	o := orm.NewOrm()
	if appId == -1 {
		sqlStr := "select * from sys_menu where main_id = 0 order by app_id asc,sort_id asc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr).QueryRows(&formatSysMenus)
		sqlCount := "select count(*) from sys_menu where main_id = 0"
		o.Raw(sqlCount).QueryRow(&count)
	} else {
		sqlStr := "select * from sys_menu where main_id = 0 and app_id = ? order by app_id asc,sort_id asc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
		o.Raw(sqlStr, appId).QueryRows(&formatSysMenus)
		sqlCount := "select count(*) from sys_menu where main_id = 0 and app_id = ?"
		o.Raw(sqlCount, appId).QueryRow(&count)
	}
	for k, v := range formatSysMenus {
		v.Sort = k + 1
		nameByte,_ := base64.StdEncoding.DecodeString(v.Name)
		v.Name = string(nameByte)
		if app, find := appHash[v.AppId]; find {
			v.AppName = app.AppName
		}
	}
	return formatSysMenus, int64(count)
}

func AddMenu(appId int,mainId int, isOuter int8, menuName string, menuPath string, sortId int) error {
	o := orm.NewOrm()
	sysMenu := &SysMenu{
		AppId:   appId,
		Name:    menuName,
		Path:    menuPath,
		IsOuter: isOuter,
		SortId:  sortId,
		MainId:  mainId,
	}
	_, err := o.Insert(sysMenu)
	if err != nil {
		fmt.Println("insert sys_menu error", err)
		return err
	}
	return nil
}

func EditMenu(id int, isOuter int8, menuName string, menuPath string, sortId int) error {
	o := orm.NewOrm()
	sysMenu := &SysMenu{Id: id}
	err := o.Read(sysMenu)
	if err != nil {
		fmt.Println("sys_menu not found", err)
		return err
	}
	sysMenu.Name = menuName
	sysMenu.Path = menuPath
	sysMenu.SortId = sortId
	sysMenu.IsOuter = isOuter
	if _, err := o.Update(sysMenu); err != nil {
		fmt.Println("update sys_menu error", err)
		return err
	}
	return nil
}

func DelFirstLevelMenu(id int) error {
	o := orm.NewOrm()
	if _, err := o.Delete(&SysMenu{Id: id}); err != nil {
		fmt.Println("delete sys_menu first error", err)
		return err
	}
	_, err := o.Raw("delete from sys_menu where main_id = ?", id).Exec()
	if err != nil {
		fmt.Println("delete sys_menu second error", err)
		return err
	}
	return nil
}

func GetSecondMenu(id int, parentName string, page, pageSize int) ([]*SecondMenu, int64) {
	o := orm.NewOrm()
	offset := (page - 1) * pageSize
	secondMenus := make([]*SecondMenu, 0)
	count := 0
	sqlStr := "select * from sys_menu where main_id = ? order by sort_id asc limit " + strconv.Itoa(offset) + "," + strconv.Itoa(pageSize)
	o.Raw(sqlStr, id).QueryRows(&secondMenus)
	sqlCount := "select count(*) from sys_menu where main_id = ?"
	o.Raw(sqlCount, id).QueryRow(&count)
	for k, v := range secondMenus {
		v.Sort = k + 1
		v.ParentName = parentName
		nameByte,_ := base64.StdEncoding.DecodeString(v.Name)
		v.Name = string(nameByte)
		if app, find := appHash[v.AppId]; find {
			v.AppName = app.AppName
		}
	}
	return secondMenus, int64(count)
}

func DelSecondLevelMenu(id int) error{
	o := orm.NewOrm()
	if _, err := o.Delete(&SysMenu{Id: id}); err != nil {
		fmt.Println("delete sys_menu second error", err)
		return err
	}
	return nil
}